/*******************************
* Students Construct Center 119			*
* C++ micro AVR Atmega 8/16 template	*
* 2012, Omsk State University			*
*****************************************/

/*******************************
* Name of project: Infra red generator
* Autors: Strokov Andrew
* Date: start 3 may 2012
********************************/

//define frequency here
#define F_CPU 12000000UL 

// includes
#include <util/delay.h>
#include <avr/interrupt.h>
#include <avr/io.h>
#include <string.h>
#include <stdlib.h>

// define UART CONSTANT
#define BAUDRATE 19200 // speed of uart
#define UART_CALC_BAUDRATE(baudRate) ((uint32_t)((F_CPU) + ((uint32_t)baudRate * 8UL)) / ((uint32_t)(baudRate) * 16UL) - 1)
#define UART_BAUD_HIGH	UBRRH
#define UART_BAUD_LOW	UBRRL
#define UART_STATUS	UCSRA
#define UART_TXREADY	UDRE
#define UART_RXREADY	RXC
#define UART_DOUBLE	U2X
#define UART_CTRL	UCSRB
#define UART_CTRL_DATA	((1<<TXEN) | (1<<RXEN))
#define UART_CTRL2	UCSRC
#define UART_CTRL2_DATA	((1<<URSEL) | (1<<UCSZ1) | (1<<UCSZ0))
#define UART_DATA	UDR

// define ports here
#define SEN		(1 << 7)
#define SCK		(1 << 5)
#define SDI		(1 << 6)
#define SDO		(1 << 4)

// other defines here
#define SC SendChar

// user global variables
uint8_t data[6];
uint8_t stroka[7];

uint8_t i;

uint8_t count = 0;
uint8_t val;
uint8_t led0 = 0;
uint8_t countVal = 0;

uint8_t n = 0;
uint32_t fail[8];

uint8_t alarm = 0;
// sending char to UART function

static void SendChar(uint8_t data) {
	while (!(UART_STATUS & (1<<UART_TXREADY)));
	UART_DATA = data;
}


// sending integer to UART function

static void SendInt(uint32_t data) {
	
	itoa(data, stroka, 10);
	for(i=0; i<=7; i++)
	{ 
	  SC(stroka[i]);
	  stroka[i] = ' ';
	}
}


// UART receive interrupt
/*
ISR(USART_RXC_vect) {
	val = UART_DATA;
	SC(' ');SC('O');SC('K');SC(' ');
	
	if(val == '1') {
		TCCR2 |= (1 << CS22)|(1 << CS21)|(1 << CS20);
	}
	if(val == '2') {
		TCCR2 &= ~(1 << CS22)& ~(1 << CS21) & ~(1 << CS20);
	}
	if(val == '3') {
		TCCR2 &= ~(1 << CS22)& ~(1 << CS21) & ~(1 << CS20);
		TCCR2 |= (1 << CS21);
	}
    if(val == 'x') {
		PORTD ^= (1 << 3);
		SC(' ');SC('O');SC('K');SC(' ');
	}


}	
*/

// timer 0 overflow
/*
ISR(TIMER0_OVF_vect) {

}
*/

// timer 0 compare
/*
ISR(TIMER0_COMP_vect) {
  
  SC('!');

}
*/

// timer 2 overflow
/*
ISR(TIMER2_OVF_vect) {

}
*/

// timer 2 compare

ISR(TIMER2_COMP_vect) {
	count++;
	TCNT2 = 0;
	if (n > 3) {
		PORTD ^= (1 << n);
		if(!(PINC & (1 << 5)))
			fail[n]++;
	}
	
	else {
		PORTC ^= (1 << n);
		if(!(PINC & (1 << 4)))
			fail[n]++;	
	}
	
	
	
	if(count > 200) {
		PORTD &= ~(1 << 4) & ~(1 << 5) & ~(1 << 6) & ~(1 << 7);
		//PORTC &= ~(1 << 0) & ~(1 << 1) & ~(1 << 2) & ~(1 << 3);
		SendInt(n);SC(':');SendInt(fail[n]);SC(',');
		if (fail[n] < 80)
			alarm = 1;
		
		fail[n] = 0;
		count = 0;
		if(n == 7) {
			n = 0;
			if(alarm) {
				SC(' ');SC('a');SC('l');SC('a');SC('r');SC('m');SC('!');
				PORTD &= ~(1 << 3);
				_delay_ms(400);
				PORTD |= (1 << 3);
			}
			SC('\r');SC('\n');
			alarm = 0;
		}
		else
			n++;

		
	}
		
}


//external interrupt 0
/*
ISR(INT0_vect) {  

}
*/


int main(void) {
	
	cli();
	
	//UART SET UP
	UART_BAUD_HIGH = (UART_CALC_BAUDRATE(BAUDRATE)>>8) & 0xFF; //set baudrate
	UART_BAUD_LOW = (UART_CALC_BAUDRATE(BAUDRATE) & 0xFF);
	UART_CTRL = UART_CTRL_DATA; //set enable UART
	UART_CTRL2 = UART_CTRL2_DATA; //set byte and other features
	//UCSRB |= (1 << RXCIE); // enable interrupts

	/* **********************************
	 *               PORTS ASSIGNMENT
	 ***********************************/
	
	DDRD |= (1 << 5)|(1 << 6)|(1 << 7)|(1 << 3)|(1 << 4);
	PORTD |= (1 << 3); // LED
	
	DDRC |= (1 << 0)|(1 << 1)|(1 << 2)|(1 << 3);
	DDRC &= ~(1 << 5) & ~(1 << 4);
	PORTC &= ~(1 << 5) & ~(1 << 4);
	
//	SC(' '); //first terminal byte
	
	
	/***********************************
	 *             THE MAIN LOOP
	 * ********************************/

	
	TIMSK |= (1 << OCIE2); // overflow interrupt by timer 2  
	
	OCR2 = 7; // output compare
	
	TCCR2 |= (1 << CS21);
	
	
	sei();
	
	
	while(1) {
		//PORTD ^= (1 << 5);
		//SendInt(countVal*11.5);
		led0++;
	}
	return 0;
}